/**
  ******************************************************************************
  * @file    :MG216-legacy.c
  * @author  :MG Team
  * @version :V1.0
  * @date
  * @brief   : for legacy adv
  ******************************************************************************
***/

/* Includes ------------------------------------------------------------------*/
#include "Includes.h"


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/



/* Private macro -------------------------------------------------------------*/
#define LEN_BLE_ADDR 6


/* Private variables ---------------------------------------------------------*/

//BLE ADV_data, maxlen=31
#define LEN_DATA 31
uint8_t adv_data[LEN_DATA] = {2,0x01,0x04,
                             19,0xff,'M','G',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
                              7,0x09,'m','g','2','x','x','T'};

/* Private function prototypes -----------------------------------------------*/
void BLE_TX_Power(uint8_t val)
{
    uint8_t data_buf[2];

    //set BLE TX Power
    data_buf[0] = 0x08;
    data_buf[1] = val; //BLE_TX_POWER; //0~1F
    MG_Write_Buffer(PA_CFG, data_buf, 2);
}

void BLE_Adv_Auto_Interv(uint32_t rc_cnt)
{
    uint8_t data_buf[4];
    uint32_t cnt_interv = rc_cnt;

    data_buf[0] = cnt_interv & 0xff;
    data_buf[1] = (cnt_interv>>8) & 0xff;
    data_buf[2] = (cnt_interv>>16) & 0xff;
    data_buf[3] = 1;   //RC_LOAD;
    MG_Write_Buffer(ADV_INTERV_RC_CFG,data_buf,4);
}

void BLE_Mode_PwrUp(void)
{
#if (POWER_SAVE_OPT == POWER_SAVE_SLEEP)
    MG_Write_Reg(0x3e, 0x01); //rcosc_pd=0, exit from sleep
#endif
}

void BLE_Mode_Sleep(void)
{
    MG_Write_Reg(BASEBAND_CFG, 6); //SLP_XO=4, STOP=2

    MG_Write_Reg(XO_PD_EN, 0x00);
    MG_Write_Reg(XO_PD_EN, 0x01); //xo_pd=1
    
    MG_Write_Reg(0x3e, 0x5); //rcosc_pd=1, dpll_pd=1
}

void BLE_Mode_LowV(void)  //now only SPI can use this option
{
    //MG_Read_Reg(0xB7); //120ms dectect
    MG_Read_Reg(0x90); //low voltage level
    MG_Read_Reg(0xAD); //low voltage enable

    BLE_SCK_SET();
}

void BLE_Mode_Stdby(void) //standby(deepsleep)
{
    MG_Write_Reg(BASEBAND_CFG, 6); //SLP_XO=4, STOP=2

    MG_Write_Reg(XO_PD_EN, 0x00);
    MG_Write_Reg(XO_PD_EN, 0x01); //xo_pd=1

    MG_Write_Reg(0x23,0x40);
    //O: irq = H, miso = L
    //I: csn/sck/mosi PU
}

#if 1
unsigned char Patch_Data5_V4x[2] = {0xa0,0x20};
unsigned char Patch_Data6_V4x[2] = {0x03,0x02};
unsigned char Patch_Data7_V4x[4] = {0x40,0x08,0x03,0x55}; //xocc|xoib


unsigned char Patch_Data0_V43[4] = {0x25,0xf4,0x33,0x55};
unsigned char Patch_Data1_V43[4] = {0xb1,0x14,0x33,0x55};
unsigned char Patch_Data2_V43[4] = {0xc0,0x0c,0x33,0x55};
unsigned char Patch_Data3_V43[4] = {0xc1,0x73,0x33,0x55};
unsigned char Patch_Data4_V43[4] = {0xc4,0xe4,0x33,0x55};
unsigned char Patch_Data5_V43[4] = {0xc5,0x2c,0x33,0x55};
unsigned char Patch_Data6_V43[4] = {0xc7,0x60,0x33,0x55};
unsigned char Patch_Data7_V43[4] = {0xb0,0xb0,0x33,0x55};
#endif
void patch(unsigned char ver)
{
    uint8_t data_buf[4] = {0x31,0x08,0x08,0x08};
    
#if (COMM_OPT_SEL == COMM_SPI)
    MG_Write_Buffer(0x3B, data_buf, 4); //csn,sck,miso input no pull
#endif

    //common patch
    MG_Write_Buffer(BG_CAL, Patch_Data5_V4x, 2);
    MG_Write_Buffer(XO_SET, Patch_Data6_V4x, 2);
    MG_Write_Buffer(ABUS_ACC, Patch_Data7_V4x, 4);
    
    if(0x42 < ver)
    {
        MG_Write_Buffer(ABUS_ACC, Patch_Data0_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data1_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data2_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data3_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data4_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data5_V43, 4);
        MG_Write_Buffer(ABUS_ACC, Patch_Data6_V43, 4);

        MG_Read_Buffer(BG_CAL, data_buf, 4);
        //if (data_buf[3] & 0x20)
        if(ValBit(data_buf[3],5))
        {
            Patch_Data7_V43[1] = ((data_buf[3] & 0x1f)<<2) | 0x80;
        }
        MG_Write_Buffer(ABUS_ACC, Patch_Data7_V43, 4);
    }
}

/*******************************************************************************
* Function   :     	BLE_Init
* Parameter  :     	void
* Returns    :     	void
* Description:      power on .BLE must initnal reg .
* Note:      :
*******************************************************************************/
void BLE_Init(void)
{
    uint8_t status = 0;
    uint8_t data_buf[5];
    //uint8_t ble_Addr[6];

    MG_Write_Reg(0x3e, 0x01); //rcosc_pd=0
    do{
#if (COMM_OPT_SEL == COMM_SPI)
        MG_Write_Reg(CONT_TEST_MODE, 8);//3 line spi. No use for I2C
#endif
        status = MG_Read_Reg(CHIP_READY);
    }while((status == 0xFF) || (status&0x4) != 0x04);
    
    MG_Write_Reg(RESET_BB, 0x1);//clear flag
    MG_Write_Reg(RESET_BB, 0x0);

    MG_Write_Reg(RESET_BB, 0xDC);//reset bb
    do{
        status = MG_Read_Reg(RESET_BB);
    }while((status&0x2) != 0x02); //reset done
    MG_Write_Reg(RESET_BB, 0x1);//clear flag
    MG_Write_Reg(RESET_BB, 0x0);

    MG_Write_Reg(XO_PD_EN, 0x1); //3//rc32k_sel, xo_pd_en
#if 1
    data_buf[4] = 0x30; //xo_pd_wait_adjust
    data_buf[3] = 0x1e;
    data_buf[2] = 0x29;
    data_buf[1] = 0x05;
    data_buf[0] = 0xdb;
    MG_Write_Buffer(XO_WAIT,data_buf,5);
#endif
    //apply patch
    status = MG_Read_Reg(IC_VER);
    patch(status);

#if 0 //debug
    Uart_Send_String("chip version=");
    Uart_Send_Byte(status);
    Uart_Send_String("\r\n");
    
    MG_Read_Buffer(0x16, ble_Addr, 6);
    Uart_Send_String("BleAddr16=");
    Uart_Send_Byte(ble_Addr[5]);
    Uart_Send_Byte(ble_Addr[4]);
    Uart_Send_Byte(ble_Addr[3]);
    Uart_Send_Byte(ble_Addr[2]);
    Uart_Send_Byte(ble_Addr[1]);
    Uart_Send_Byte(ble_Addr[0]);
    Uart_Send_String("\r\n");
#endif

#if 1  //dcdc
    data_buf[0] = MG_Read_Reg(PA_CFG);
    if(!ValBit(data_buf[0],0)) //DcDc on
    {
        data_buf[4] = 0x03; //buck_dly_set
        data_buf[3] = 0x90; //buck_dly_set
        data_buf[2] = 0xb0;
        data_buf[1] = 0x30;
        data_buf[0] = 0xe0;
        MG_Write_Buffer(0x17,data_buf,5);
    }
#endif

    //set BLE TX Power
    data_buf[0] = 0x08;
    data_buf[1] = BLE_TX_POWER; //max 1F
    MG_Write_Buffer(PA_CFG, data_buf, 2);

    MG_Write_Reg(CONFIG, 0x87); //PREAMBLE_LEN_AUTO | SCRAMBLE_ON | CRC_EN | POWER_UP
    MG_Write_Reg(INT_MASK, 0x6F); //sleep int
}

/*******************************************************************************
* Function   :     	BLE_TX
* Parameter  :     	none
* Returns    :     	void
* Description:      Beacon data .process .
* Note:      :
*******************************************************************************/
void BLE_TX()
{
    uint8_t data_buf[3];

    BLE_Mode_PwrUp();

    BLE_Adv_Auto_Interv(CNT_ADV_INTERV);

    //BLT FIFO write adv_data . max len:31 byte
    MG_Write_Buffer(W_TX_PAYLOAD, adv_data, LEN_DATA);

    //PDU TYPE: 2  non-connectable undirected advertising . tx add:random address
    //set BLT PDU length:adv_data+6 mac adress.
    data_buf[0] = 0x08;
    data_buf[1] = ADV_NONCONN_IND|ADV_TXADD_RANDOM;
    data_buf[2] = LEN_DATA+LEN_BLE_ADDR;
    MG_Write_Buffer(ADV_PKT_CFG, data_buf, 3);

    MG_Write_Reg(BASEBAND_CFG, 5); //SLP_XO=4, STOP=2, WKUP_EN=1
    MG_Write_Reg(WAKEUP_NOW, 1);
    
#if (COMM_OPT_SEL == COMM_I2C_SIMU_NOPU)
    GPIO_Init(BLE_SCL_PORT,BLE_SCL,GPIO_Mode_Out_OD_HiZ_Slow);
    GPIO_Init(BLE_SDA_PORT,BLE_SDA,GPIO_Mode_Out_OD_HiZ_Slow);
#endif

}
